package com.lianjia.crawler.parser;

import com.lianjia.crawler.model.HouseInfo;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 房屋信息解析器，用于从HTML中提取房屋信息
 */
public class HouseParser {
    private static final Logger logger = LoggerFactory.getLogger(HouseParser.class);
    
    /**
     * 从HTML中提取房屋信息列表
     *
     * @param html HTML内容
     * @return 房屋信息列表
     */
    public static List<HouseInfo> parseHouseList(String html) {
        if (html == null || html.trim().isEmpty()) {
            logger.warn("HTML内容为空");
            return null;
        }
        
        // 与Python版本一致，打印HTML长度
        System.out.println("正在尝试解析 " + html.length());
        logger.info("正在尝试解析HTML，长度: {}", html.length());
        
        // 如果HTML长度不是1101，保存页面内容到文件
        if (html.length() != 1101) {
            saveHtmlToFile(html);
        } else {
            logger.warn("检测到HTML长度为1101，可能是反爬虫机制返回的空页面");
            System.out.println("检测到HTML长度为1101，可能是反爬虫机制返回的空页面");
        }
        
        // 检查是否包含JavaScript反爬机制
        if ( html.contains("人机身份认证")) {
            logger.warn("检测到反爬虫机制，HTML包含验证码或JavaScript代码");
            System.out.println("检测到反爬虫机制，请稍后再试");
            return null;
        }
        
        List<HouseInfo> infoList = new ArrayList<>();
        
        try {
            Document doc = Jsoup.parse(html);
            
            // 打印页面标题，帮助调试
            String title = doc.title();
            logger.info("页面标题: {}", title);
            System.out.println("页面标题: " + title);
            
            // 检查是否是错误页面
            if (title.contains("验证") || title.contains("访问验证") || title.contains("出错了")) {
                logger.warn("页面可能需要验证或出错: {}", title);
                System.out.println("页面可能需要验证或出错: " + title);
                return null;
            }
            
            Elements liList = doc.select("ul.sellListContent > li");
            
            if (liList.isEmpty()) {
                // 尝试其他可能的选择器
                liList = doc.select("li.LOGVIEWDATA");
                if (liList.isEmpty()) {
                    logger.warn("未找到房屋列表元素，HTML长度: {}, 页面标题: {}", html.length(), title);
                    
                    // 保存HTML片段用于调试
                    String htmlFragment = html.length() > 500 ? html.substring(0, 500) + "..." : html;
                    logger.debug("HTML片段: {}", htmlFragment);
                    
                    return null;
                }
            }
            
            logger.info("找到 {} 个房源列表项", liList.size());
            System.out.println("找到 " + liList.size() + " 个房源列表项");
            
            for (Element li : liList) {
                HouseInfo info = new HouseInfo();
                
                // 提取标题
                Element titleElem = li.selectFirst("div.info.clear div.title > a");
                if (titleElem != null) {
                    info.setTitle(titleElem.text());
                }
                
                // 提取地址
                Elements locationElems = li.select("div.info.clear div.flood div.positionInfo > a");
                if (!locationElems.isEmpty()) {
                    StringBuilder location = new StringBuilder();
                    for (int i = 0; i < locationElems.size(); i++) {
                        location.append(locationElems.get(i).text());
                        if (i < locationElems.size() - 1) {
                            location.append(", ");
                        }
                    }
                    info.setLocation(location.toString());
                }
                
                // 提取房屋细节
                Element detailsElem = li.selectFirst("div.info.clear div.address > div");
                if (detailsElem != null) {
                    String detailsText = detailsElem.text();
                    String[] details = detailsText.split("\\s*\\|\\s*");
                    info.setDetails(categorizeDetails(details));
                }
                
                // 提取价格
                HouseInfo.Price price = new HouseInfo.Price();
                
                Element totalPriceElem = li.selectFirst("div.info.clear div.priceInfo div.totalPrice > span");
                if (totalPriceElem != null) {
                    price.setTotalPrice(totalPriceElem.text() + " 万");
                }
                
                Element unitPriceElem = li.selectFirst("div.info.clear div.priceInfo div.unitPrice");
                if (unitPriceElem != null) {
                    String unitPrice = unitPriceElem.attr("data-price");
                    if (unitPrice != null && !unitPrice.isEmpty()) {
                        price.setUnitPrice(unitPrice + " 元");
                    }
                }
                
                info.setPrice(price);
                
                // 提取图片URL
                Element imgElem = li.selectFirst("a.noresultRecommend.img.LOGCLICKDATA img.lj-lazy");
                if (imgElem != null) {
                    info.setImage(imgElem.attr("data-original"));
                } else {
                    // 尝试其他可能的选择器
                    imgElem = li.selectFirst("img.lj-lazy");
                    if (imgElem != null) {
                        info.setImage(imgElem.attr("data-original"));
                    }
                }
                
                // 提取链接
                Element linkElem = li.selectFirst("div.info.clear div.title > a");
                if (linkElem != null) {
                    info.setLink(linkElem.attr("href"));
                }
                
                infoList.add(info);
            }
            
            return infoList;
        } catch (Exception e) {
            logger.error("解析HTML失败: {}", e.getMessage(), e);
            System.out.println("解析HTML失败: " + e.getMessage());
            return null;
        }
    }
    
    /**
     * 将HTML内容保存到文件
     *
     * @param html HTML内容
     */
    private static void saveHtmlToFile(String html) {
        try {
            // 创建result/debug目录（如果不存在）
            File debugDir = new File("result/debug");
            if (!debugDir.exists()) {
                debugDir.mkdirs();
            }
            
            // 使用时间戳作为文件名
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            String timestamp = sdf.format(new Date());
            String fileName = "html_" + timestamp + "_" + html.length() + ".html";
            File file = new File(debugDir, fileName);
            
            // 写入文件
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write(html.getBytes(StandardCharsets.UTF_8));
            }
            
            logger.info("已保存HTML内容到文件: {}", file.getAbsolutePath());
            System.out.println("已保存HTML内容到文件: " + file.getAbsolutePath());
        } catch (IOException e) {
            logger.error("保存HTML文件失败: {}", e.getMessage(), e);
            System.out.println("保存HTML文件失败: " + e.getMessage());
        }
    }
    
    /**
     * 将房屋细节字符串数组分类
     *
     * @param details 细节字符串数组
     * @return 分类后的细节Map
     */
    private static Map<String, String> categorizeDetails(String[] details) {
        Map<String, String> categorized = new HashMap<>();
        
        // 定义特征关键词，与Python版本保持一致
        Map<String, String[]> features = new HashMap<>();
        features.put("configuration", new String[]{"室", "厅"});
        features.put("area", new String[]{"平米"});
        features.put("towards", new String[]{"东", "南", "西", "北"});
        features.put("decorate", new String[]{"精装", "简装", "毛坯"});
        features.put("storey", new String[]{"层"});
        features.put("period", new String[]{"年"});
        features.put("categorie", new String[]{"板塔结合", "板楼", "塔楼"});
        
        // 使用与Python版本相似的逻辑
        for (String detail : details) {
            if (detail == null || detail.trim().isEmpty()) {
                continue;
            }
            
            for (Map.Entry<String, String[]> entry : features.entrySet()) {
                String key = entry.getKey();
                String[] values = entry.getValue();
                
                for (String value : values) {
                    if (detail.contains(value)) {
                        categorized.put(key, detail);
                        break;
                    }
                }
            }
        }
        
        return categorized;
    }
    
    /**
     * 从图片URL中提取文件名
     *
     * @param url 图片URL
     * @return 文件名
     */
    public static String extractImageFileName(String url) {
        Pattern pattern = Pattern.compile("https://image1\\.ljcdn\\.com/110000-inspection/(.+?)\\.(\\d+)x(\\d+)\\.jpg$");
        Matcher matcher = pattern.matcher(url);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }
} 